package o2o.web.actions.company.postman;

import com.jinyou.utils.common.DateUtils;
import com.jinyou.utils.common.ObjectUtils;
import com.jinyou.utils.common.ValidateUtil;
import com.jinyouapp.common.tools.jms.model.JMSNotify;
import o2o.cache.company.postman.*;
import o2o.config.dao.UserDaoSql;
import o2o.config.jms.config.JMSTypeContent;
import o2o.config.jms.sender.JmsSender;
import o2o.dao.PO.PojoTables;
import o2o.dao.PO.company.postman.*;
import o2o.dao.VO.company.postman.PostCompanyInfoVO;
import o2o.dao.VO.company.postman.PostTypeInfoVO;
import o2o.service.company.postman.ShopSignCompanyService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import java.sql.Connection;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 *
 * @User: @Created by yangtk
 * @Date: @Date 2019/7/31 10:38
 * @Classname: PostCompanyMan
 * @To 配送公司相关设置
 */

public class PostCompanyMan {

    //  设置
    public static void modifyCompanyType(String updateUser, String typeIds, Long companyId) throws Exception {
        if (companyId == null) {
            throw new Exception("公司id不能为空");
        }
        Connection con = null;
        try {
            con = UserDaoSql.getInstance().getConnection(true);
            Set<Long> set = CompanyTypeRelationMemory.getInstance().listOfByCompanyId(companyId);
            if (set != null && set.size() > 0) {
                StringBuilder delSql = new StringBuilder();
                delSql.append("update ").append(PojoTables.COMPANY_TYPE_RELATION)
                        .append(" set updateUser =").append("'").append(updateUser).append("'")
                        .append(", delFlag = 1").append(" where ")
                        .append(" delFlag = 0 and companyId =").append(companyId);
                try {
                    UserDaoSql.getInstance().executeBySql(delSql.toString(), con);
                } catch (Exception e) {
                    e.printStackTrace();
                    con.rollback();
                    UserDaoSql.getInstance().close(con);
                    throw new Exception(e.getMessage());
                }
            }
            // 插入

            if (StringUtils.isNotEmpty(typeIds)) {
                String[] split = StringUtils.split(typeIds, ",");
                Set<Long> typeIdSet = new HashSet<>();
                if (split.length != 0) {
                    for (String tmp : split) {
                        try {
                            long l = Long.parseLong(tmp);
                            typeIdSet.add(l);
                        } catch (Exception e) {
                            e.printStackTrace();
                            continue;
                        }
                    }
                }
                if (!typeIdSet.isEmpty()) {
                    Long cTime = DateUtils.getCurrTime();
                    List<CompanyTypeRelationInfo> insertList = new ArrayList<>();
                    for (Long typeId : typeIdSet) {
                        if (checkTypeIdIn(typeId)) {
                            CompanyTypeRelationInfo info = new CompanyTypeRelationInfo();
                            info.setCompanyId(companyId).setTypeId(typeId).setCreateUser(updateUser)
                                    .setCreateTime(cTime).setDelFlag(0);
                            insertList.add(info);
                        }
                    }
                    if (!insertList.isEmpty()) {
                        for (CompanyTypeRelationInfo info : insertList) {
                            if (info != null) {
                                try {
                                    UserDaoSql.getInstance().saveObj(PojoTables.COMPANY_TYPE_RELATION, info, con);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
            }
            con.commit();
        } catch (Exception e) {
            e.printStackTrace();
            UserDaoSql.getInstance().rollback(con);
            throw e;
        } finally {
            UserDaoSql.getInstance().close(con);
        }
        // 缓存
        CompanyTypeRelationMemory.getInstance().reload(companyId);
        // 数据同步
        JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.COMPANY_POST_DELIVERY_TYPE_INFO_RELOAD).setLong01(companyId);
        JmsSender.setTopicSender(notify);
    }

    // 获取公司信息
    public static PostCompanyInfoVO getPostCompany(PostCompanyInfo info, Integer type) {
        PostCompanyInfoVO infoVO = new PostCompanyInfoVO();
        try {
            ObjectUtils.copyPropertiesExclude(info, infoVO);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        // 签约的骑手数量处理
        List<PostmanSignCompanyInfo> signInfos = PostmanSignCompanyMemory.getInstance().listOfCompanyId(info.getId(), null, type, SIGN_COMPANY_STATUS.pass);
        infoVO.setPostmanNumber(signInfos != null ? signInfos.size() : 0);
        // 商户数量
        infoVO.setShopNumber(Integer.parseInt(ShopSignCompanyService.getInstance().countOfCompanyIdAndType(info.getId()) + ""));
        List<PostTypeInfoVO> typeInfoVOList = listOfPostTypeInfoVOByCompanyId(info.getId(), type);
        if (typeInfoVOList != null && !typeInfoVOList.isEmpty()) {
            infoVO.setPostTypeInfoList(typeInfoVOList);
        }
        return infoVO;
    }

    // 获取公司对应的类型信息
    public static List<PostTypeInfoVO> listOfPostTypeInfoVOByCompanyId(Long companyId, Integer type) {
        if (companyId != null) {
            Set<Long> set = CompanyTypeRelationMemory.getInstance().listOfByCompanyId(companyId);
            if (set == null) {
                return null;
            }
            List<PostTypeInfoVO> list = new ArrayList<>();
            for (Long id : set) {
                if (id == null) {
                    continue;
                }
                PostTypeInfo typeInfo = PostTypeMemory.getInstance().getById(id);

                if (typeInfo == null) {
                    continue;
                }
                if (type != null && type != typeInfo.getType()) {
                    continue;
                }
                PostTypeInfoVO infoVO = new PostTypeInfoVO();
                try {
                    ObjectUtils.copyPropertiesExclude(typeInfo, infoVO);
                } catch (Exception e) {
                    e.printStackTrace();
                    continue;
                }
                list.add(infoVO);
            }
            return list;
        }
        return null;
    }

    // 骑手申请公司签约
    public static void postmanApplyCompany(PostCompanyInfo companyInfo, String username, int type) throws Exception {
        PostTypeInfo code = PostTypeMemory.getInstance().getByCode(type);
        if (code == null) {
            throw new Exception("未获取到类型");
        }
        // 先查询一下
        StringBuilder sql = new StringBuilder();
        sql.append("select *  from ").append(PojoTables.POSTMAN_SIGN_COMPANY)
                .append(" where delFlag = 0 and username='").append(username).append("'").append(" and postTypeId = ").append(code.getId())
                .append(" and  companyId = ").append(companyInfo.getId());
        List<PostmanSignCompanyInfo> list = null;
        try {
            list = (List<PostmanSignCompanyInfo>) UserDaoSql.getInstance().list(PostmanSignCompanyInfo.class, sql.toString());
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("数据库连接错误");
        }
        if (list == null) {

        } else {
            Long applyId = null;
            for (PostmanSignCompanyInfo tempInfo : list) {
                if (tempInfo == null) {
                    continue;
                }
                if (tempInfo.getStatus() == SIGN_COMPANY_STATUS.apply) {
                    throw new Exception("您已经申请过了,无需重复申请");
                } else if (tempInfo.getStatus() == SIGN_COMPANY_STATUS.pass) {
//                    List<PostmanSignCompanyInfo> relationInfoList = PostmanSignCompanyMemory.getInstance().listOfPostman(username, companyInfo.getId(), type);
//                    if (relationInfoList == null || relationInfoList.isEmpty()) {
//                        applyId = tempInfo.getId();
//                        break;
//                    } else {
                    throw new Exception("您已签约过该公司的指定类型");
//                    }
                } else {
                    // 拒绝了
                    applyId = tempInfo.getId();
                    break;
                }
            }
            if (applyId != null) {
                // 再次申请
                StringBuilder updateSql = new StringBuilder();
                updateSql.append("update ")
                        .append(PojoTables.POSTMAN_SIGN_COMPANY)
                        .append(" set ").append(" updateUser = '").append(username).append("'")
                        .append(",status = ").append(SIGN_COMPANY_STATUS.apply)
                        .append(",applyTime=").append(DateUtils.getCurrTime())
                        .append(" where delFlag = 0 and id = ").append(applyId);
                try {
                    UserDaoSql.getInstance().executeBySql(updateSql.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("更新错误,请稍后重试");
                    throw new Exception(e.getMessage());
                }
                PostmanSignCompanyMemory.getInstance().modify(applyId);
                // 数据通讯
                JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.COMPANY_POSTMAN_SIGN_UPDATE).setLong01(applyId);
                JmsSender.setTopicSender(notify);

                return;
            }
        }
        // 未申请过。。。
        PostCompanyInfoVO companyInfoVO = PostCompanyMan.getPostCompany(companyInfo, null);
        if (companyInfoVO == null) {
            throw new Exception("获取失败,请稍后重试");
        }
        List<PostTypeInfoVO> typeInfoList = companyInfoVO.getPostTypeInfoList();
        if (typeInfoList == null) {
            throw new Exception("未获取到公司类型信息");
        }
        boolean isHasType = false;
        PostTypeInfoVO postTypeInfoVO = null;
        for (PostTypeInfoVO infoVO : typeInfoList) {
            if (infoVO != null && infoVO.getType() != null && infoVO.getType() == type) {
                isHasType = true;
                postTypeInfoVO = infoVO;
                break;
            }
        }
        if (!isHasType) {
            throw new Exception("该公司未有您选择的类型");
        }
        Long cTime = DateUtils.getCurrTime();
        // 添加一条数据
        PostmanSignCompanyInfo applyCompanyInfo = new PostmanSignCompanyInfo();
        applyCompanyInfo.setCompanyId(companyInfo.getId()).setCreateTime(cTime).setDelFlag(0).setPostType(type)
                .setCreateUser(username).setPostTypeId(postTypeInfoVO.getId()).setApplyTime(cTime).setUsername(username);
        try {
            UserDaoSql.getInstance().insertObj(PojoTables.POSTMAN_SIGN_COMPANY, applyCompanyInfo);
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("请求失败,请稍后重试");
        }
        // 结束
        PostmanSignCompanyMemory.getInstance().add(cTime);
        // 数据通讯
        JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.COMPANY_POSTMAN_SIGN_ADD).setLong01(cTime);
        JmsSender.setTopicSender(notify);
    }

    // 配送公司签约 或者拒绝
    public static void postmanSignCompanyDeal(String opUser, PostCompanyInfo companyInfo, Long id, Integer status, String reason) throws Exception {
        Long cTime = DateUtils.getCurrTime();
        StringBuilder sql = new StringBuilder();
        sql.append("select * ").append(" from ")
                .append(PojoTables.POSTMAN_SIGN_COMPANY)
                .append(" where delFlag = 0")
                .append(" and id =").append(id).append(" and status = ").append(SIGN_COMPANY_STATUS.apply)
        ;
        PostmanSignCompanyInfo applyCompanyInfo = null;
        try {
            applyCompanyInfo = (PostmanSignCompanyInfo) UserDaoSql.getInstance().getObject(PostmanSignCompanyInfo.class, sql.toString());
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("获取信息失败,请稍后重试1");
        }
        if (applyCompanyInfo == null) {
            throw new Exception("获取信息失败,请稍后重试2");
        }
        if (companyInfo.getId().longValue() - applyCompanyInfo.getCompanyId() != 0) {
            throw new Exception("请核实您的公司信息");
        }
        if (applyCompanyInfo.getPostTypeId() == null) {
            throw new Exception("配送类型信息不能为空");
        }
//        Connection con = getCon(true);
        StringBuilder updateSql = new StringBuilder();
        updateSql.append(" update ").append(PojoTables.POSTMAN_SIGN_COMPANY)
                .append(" set status = ").append(status)
                .append(",updateUser ='").append(opUser).append("'").append(",dealTime =").append(cTime);
        if (status == SIGN_COMPANY_STATUS.refuse) {
            if (StringUtils.isNotEmpty(reason)) {
                updateSql.append(",refuseReason=").append("'")
                        .append(reason).append("'");
            }
        }
        updateSql.append(" where id =").append(id);
        try {
            UserDaoSql.getInstance().executeBySql(updateSql.toString());
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("操作失败,请稍后重试");
        }
        PostmanSignCompanyMemory.getInstance().modify(id);
        // 数据通讯
        JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.COMPANY_POSTMAN_SIGN_UPDATE).setLong01(id);
        JmsSender.setTopicSender(notify);
    }

    // 配送公司签约 或者拒绝
    public static void shopApplyCompanyDeal(String opUser, PostCompanyInfo companyInfo, Long id, Integer status, String reason) throws Exception {
        Long cTime = DateUtils.getCurrTime();
        StringBuilder sql = new StringBuilder();
        sql.append("select * ").append(" from ")
                .append(PojoTables.SHOP_SIGN_COMPANY)
                .append(" where delFlag = 0")
                .append(" and id =").append(id).append(" and status = ").append(SIGN_COMPANY_STATUS.apply);
        ShopSignCompanyInfo signCompanyInfo = null;
        try {
            signCompanyInfo = (ShopSignCompanyInfo) UserDaoSql.getInstance().getObject(ShopSignCompanyInfo.class, sql.toString());
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("获取信息失败,请稍后重试");
        }
        if (signCompanyInfo == null) {
            throw new Exception("获取信息失败,请稍后重试");
        }
        if (companyInfo.getId().longValue() - signCompanyInfo.getCompanyId() != 0) {
            throw new Exception("请核实您的公司信息");
        }
        StringBuilder updateSql = new StringBuilder();
        updateSql.append(" update ").append(PojoTables.SHOP_SIGN_COMPANY)
                .append(" set status = ").append(status)
                .append(",updateUser ='").append(opUser).append("'").append(",dealTime =").append(cTime);
        if (status == SIGN_COMPANY_STATUS.refuse) {
            if (StringUtils.isNotEmpty(reason)) {
                updateSql.append(",refuseReason=").append("'")
                        .append(reason).append("'");
            }
        }
        updateSql.append(" where id =").append(id);
        try {
            UserDaoSql.getInstance().executeBySql(updateSql.toString());
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("操作失败,请稍后重试");
        }
        // 更新缓存
        ShopSignCompanyService.getInstance().updateCacheOfShopSign(signCompanyInfo.getShopId());
        try {
            // 数据通讯
            JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.SHOP_SIGN_COMPANY_MODIFY)
                    .setLong01(signCompanyInfo.getShopId());
            JmsSender.setTopicSender(notify);
        } catch (Exception e) {
        }
    }

    // 检测配送公司的类型是否在平台所属类型里面
    public static boolean checkTypeIdIn(Long id) {
        if (id == null) {
            return false;
        }
        Set<Long> set = listOfPostmanTypeBy(null);
        return isInContain(set, id);
    }


    // 获取骑手的类型信息
    public static List<PostTypeInfoVO> listOfPostTypeInfoByPostman(String username, Integer type) {
        if (StringUtils.isEmpty(username)) {
            return null;
        }
        Set<Long> set = PostmanTypeRelationMemory.getInstance().listOfByPostman(username);
        if (set != null) {
            List<PostTypeInfo> list = new ArrayList<>();
            for (Long id : set) {
                PostTypeInfo typeInfo = PostTypeMemory.getInstance().getById(id);

                if (typeInfo == null) {
                    continue;
                }
                if (type != null && type != typeInfo.getType()) {
                    continue;
                }
                list.add(typeInfo);
            }
            List<PostTypeInfoVO> infoVOS = null;
            if (type != null) {
                infoVOS = list.stream().filter(a -> a.getType() == type).map(a -> a.convert2VO()).collect(Collectors.toList());
            } else {
                infoVOS = list.stream().map(a -> a.convert2VO()).collect(Collectors.toList());
            }
            return infoVOS;
        }
        return null;
    }


    // 查看指定id是不是在集合内
    public static boolean isInContain(Set<Long> set, Long id) {
        if (set == null || set.isEmpty() || id == null) {
            return false;
        }
        for (Long tId : set) {
            if (tId.longValue() - id.longValue() == 0) {
                return true;
            }
        }
        return false;
    }


    public static List<PostTypeInfo> listOfPostmanType(Integer openState) {
        Set<Long> set = listOfPostmanTypeBy(openState);
        if (set != null && !set.isEmpty()) {
            List<PostTypeInfo> list = new ArrayList<>();
            for (Long id : set) {
                PostTypeInfo typeInfo = PostTypeMemory.getInstance().getById(id);
                list.add(typeInfo);
            }
            return list;
        }
        return null;
    }

    // get postmanType
    public static Set<Long> listOfPostmanTypeBy(Integer openState) {
        List<PostTypeInfo> list = PostTypeMemory.getInstance().list(openState);
        if (list != null && !list.isEmpty()) {
            Set<Long> typeIdSet = new HashSet<>();
            for (PostTypeInfo info : list) {
                if (info != null && info.getId() != null) {
                    typeIdSet.add(info.getId());
                }
            }
            return typeIdSet;
        }
        return null;
    }

    // *** 骑手已签约指定类型的获取已经签约的配送公司*******************
    public static Set<Long> listCompanyIdSetByPostman(String postman, Integer type) {
        if (StringUtils.isEmpty(postman)) {
            return null;
        }
        List<PostmanSignCompanyInfo> infos = PostmanSignCompanyMemory.getInstance().listOfPostman(postman, null, type, SIGN_COMPANY_STATUS.pass);
        return infos == null || infos.isEmpty() ? null : infos.stream().map(a -> a.getCompanyId()).collect(Collectors.toSet());
    }


    // 商家获取未签约的配送公司信息
    public static List<PostCompanyInfoVO> listOfShopCanSignPostCompany(Long shopId, String city, String county, String comType, Integer type) {
        // Set<Integer> signStatus = new HashSet<>();
        // signStatus.add(SIGN_COMPANY_STATUS.pass);
        // signStatus.add(SIGN_COMPANY_STATUS.apply);
        List<PostCompanyInfo> postCompanyInfoList = listOfPostCompanyByCity(city, county, comType, type);
        if (!ValidateUtil.isAbsList(postCompanyInfoList)) {
            return Collections.emptyList();
        }
        // 已经签约配送公司信息
        List<ShopSignCompanyInfo> companyInfos = ShopSignCompanyService.getInstance().listSignByShopId(shopId, null);
        // 已经通过的
        Set<Long> aredaySet = companyInfos.stream().filter(b -> b.getStatus() == SIGN_COMPANY_STATUS.pass).map(b -> b.getCompanyId()).collect(Collectors.toSet());
        Map<Long, ShopSignCompanyInfo> map = companyInfos.stream().filter(b -> b.getStatus() != SIGN_COMPANY_STATUS.pass).collect(Collectors.toMap(ShopSignCompanyInfo::getCompanyId, Function.identity(), (b1, b2) -> b2));
        List<PostCompanyInfoVO> reList = new ArrayList<>();
        if (ValidateUtil.isAbsList(postCompanyInfoList)) {
            final Set<Long> companySet = aredaySet;
            reList = postCompanyInfoList.stream().filter(b -> !companySet.contains(b.getId()))
                    .map(b -> {
                        PostCompanyInfoVO companyInfoVO = new PostCompanyInfoVO();
                        BeanUtils.copyProperties(b, companyInfoVO);
                        if (map.get(b.getId()) != null) {
                            companyInfoVO.setShopSignStatus(map.get(b.getId()).getStatus());
                        }
                        // 获取
                        List<PostTypeInfoVO> typeInfoVOList = listOfPostTypeInfoVOByCompanyId(companyInfoVO.getId(), type);
                        if (typeInfoVOList != null && !typeInfoVOList.isEmpty()) {
                            companyInfoVO.setPostTypeInfoList(typeInfoVOList);
                        }
                        return companyInfoVO;
                    })
                    .collect(Collectors.toList());
        }
        return reList;
    }


    // 获取 指定类型的  配送公司
    public static List<PostCompanyInfo> listOfPostCompanyByCity(String city, String county, String comType, Integer type) {
        // 拿到所有的信息
        List<PostCompanyInfo> postCompanyInfoList = PostCompanyMemory.getInstance().listOfCity(city, comType);
        if (!ValidateUtil.isAbsList(postCompanyInfoList)) {
            return Collections.emptyList();
        }
        return
                postCompanyInfoList.stream().filter(a -> {
                    if (StringUtils.isNotEmpty(county)) {
                        if (StringUtils.isEmpty(a.getCounty()) || !a.getCounty().contains(county)) {
                            return false;
                        }
                    }
                    if (type != null) {
                        List<PostTypeInfoVO> typeInfoVOS = PostCompanyMan.listOfPostTypeInfoVOByCompanyId(a.getId(), type);
                        if (typeInfoVOS == null || typeInfoVOS.isEmpty()) {
                            return false;
                        }
                    }
                    return true;
                }).collect(Collectors.toList());
    }


}
